package utils

import (
	"bytes"
	"compress/gzip"
	"crypto/md5"
	"encoding/base64"
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"regexp"
	"strings"
	"time"
)

// 过滤掉特殊字符
const pattern = "[`~!@#$%^&*()_\\-+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？0-9]"

// 身份证号正则
const idcardPatter = `[\s]?(([1-6]\d{5})(19\d{2}|20\d{2})(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])(\d{3}[\dxX]))`

// 获取当前中国时间
func GetCNTimeNow() (timestamp int64) {
	var cnZone = time.FixedZone("CST", 8*3600)
	timestamp = time.Now().In(cnZone).UnixNano() / 1e6
	return
}

// Md5算法
func Md5(str string) (md5str string) {
	data := []byte(str)
	has := md5.Sum(data)
	md5str = fmt.Sprintf("%x", has)
	return
}

// 验证是否是姓名
func IsName(str string) bool {
	return !regexp.MustCompile(pattern).MatchString(str)
}

// 验证身份证
func IsIdCard(idcard string) bool {
	return regexp.MustCompile(idcardPatter).MatchString(idcard)
}

// zap logger
func NewZapLogger(logLevel string) (logger *zap.Logger, err error) {
	config := zap.Config{
		Level:       zap.NewAtomicLevelAt(SetLogLevel(logLevel)),
		Development: false,
		Sampling: &zap.SamplingConfig{
			Initial:    100,
			Thereafter: 100,
		},
		Encoding:         "json",
		EncoderConfig:    zap.NewProductionEncoderConfig(),
		OutputPaths:      []string{"stderr"},
		ErrorOutputPaths: []string{"stderr"},
	}
	logger, err = config.Build()
	if err != nil {
		return
	}
	return
}

// 设置log级别
func SetLogLevel(level string) zapcore.Level {
	// 设置级别
	logLevel := zap.DebugLevel
	switch strings.ToLower(level) {
	case "debug":
		logLevel = zap.DebugLevel
	case "info":
		logLevel = zap.InfoLevel
	case "warn":
		logLevel = zap.WarnLevel
	case "error":
		logLevel = zap.ErrorLevel
	case "panic":
		logLevel = zap.PanicLevel
	case "fatal":
		logLevel = zap.FatalLevel
	default:
		logLevel = zap.InfoLevel
	}
	return logLevel
}


// 暂时不启用压缩
func gzipData(data string) ([]byte, error) {
	var buf bytes.Buffer
	zw := gzip.NewWriter(&buf)
	defer zw.Close()
	_, err := zw.Write([]byte(data))
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// 对数据进行编码
func encodeData(data string) (string, error) {
	gdata, err := gzipData(data)
	if err != nil {
		return "", err
	}
	encoded := base64.StdEncoding.EncodeToString(gdata)
	return encoded, nil
}